﻿using System.Linq;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using SmartCard.Framework.ApiPlugins.FileSystem;

namespace SmartCard.Framework.UnitTests
{
	[TestClass]
	public class SmartCardReaderManagerTests
	{
		/// <summary>
		/// Simple construction test of the manger to ensure we have two smart
		/// card readers.
		/// </summary>
		[TestMethod]
		public void ConstructManager()
		{
			var manager = new DefaultFrameworkCardReaderManager();

			Assert.IsTrue(manager.ManagedSmartCardReaders.Count() > 0,
				"The system should have found at least a single reader");
		}

		/// <summary>
		/// This test ensures that the manager forwards card insertion
		/// notifications of the reader to the client.
		/// </summary>
		[TestMethod]
		public void ManagerCardInsertedTest()
		{
			#region assemble
			
			var manager = new DefaultFrameworkCardReaderManager();
			var insertedEvent = new ManualResetEvent(false);
			var removedEvent = new ManualResetEvent(false);

			// inline to make more contained test
			manager.CardInserted += (sender, e) =>
				{
					insertedEvent.Set();
				};

			manager.CardRemoved += (sender, e) =>
				{
					removedEvent.Set();
				};

			// lets grab the file system reader and "insert" a card,
			// we will use the "contact reader"
			var reader = manager.ManagedSmartCardReaders.Where((x) =>
				x.GetType().Equals(typeof(FileSystemReader)) &&
				x.ReaderType == eReaderType.Contact).Single() as FileSystemReader;

			#endregion

			#region activate and assert results
			
			// we will give it one second.  very generous :)
			reader.InsertCard();
			var waitResult = insertedEvent.WaitOne(1000);
			Assert.IsTrue(waitResult, "The card insertion was never signaled by the manager");

			// we will remove the card and give it one second
			Assert.IsFalse(removedEvent.WaitOne(500), "Card removed event was triggered when nothing had been removed");
			reader.RemoveCard();
			waitResult = removedEvent.WaitOne(1000);
			Assert.IsTrue(waitResult, "The card removal event was never signaled");

			#endregion
		}
	}
}
